using Microsoft.Web.WebView2.WinForms;
using Sunny.UI;
using WinApp.Models;
using WinApp.Services;
using System.Drawing;

namespace WinApp.Pages
{
    public partial class PageActionGroups : UIPage
    {
        private WebView2 _webView;
        private PageRunner _pageRunner;
        private UINavBar _navBar;
        public PageActionGroups(WebView2 webView2 = null)
        {
            _webView = webView2;
            InitializeComponent();
            dgvActions.AutoGenerateColumns = false;
            BindGroupTypeComboBox();
            LoadData();
        }

        public PageRunner Runner
        {
            set { _pageRunner = value; }
        }

        public UINavBar NavBar
        {
            set { _navBar = value; }
        }
        #region 类型控制
        private void BindGroupTypeComboBox()
        {
            List<GroupTypeComboBoxItem> list = new List<GroupTypeComboBoxItem>
            {
                new GroupTypeComboBoxItem { DisplayText = "顺序", Value = ActionGroupType.Sequential },
                new GroupTypeComboBoxItem { DisplayText = "分支", Value = ActionGroupType.Branch },
                new GroupTypeComboBoxItem { DisplayText = "循环", Value = ActionGroupType.Loop },
                new GroupTypeComboBoxItem { DisplayText = "定次", Value = ActionGroupType.FixedCount }
            };
            cmbGroupType.DataSource = list;
            cmbGroupType.DisplayMember = "DisplayText";
            cmbGroupType.ValueMember = "Value";
        }

        private void cmbGroupType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbGroupType.SelectedItem == null)
                return;
            GroupTypeComboBoxItem cbi = cmbGroupType.SelectedItem as GroupTypeComboBoxItem;
            switch (cbi.Value)
            {
                case ActionGroupType.Sequential:
                    cmbParam1Type.DataSource = null;
                    cmbParam1Type.Enabled = false;
                    cmbParam1Value.DataSource = null;
                    cmbParam1Value.Enabled = false;
                    cmbParam2Type.DataSource = null;
                    cmbParam2Type.Enabled = false;
                    cmbParam2Value.DataSource = null;
                    cmbParam2Value.Enabled = false;
                    cmbCondition.DataSource = null;
                    cmbCondition.Enabled = false;
                    break;
                case ActionGroupType.Branch:
                case ActionGroupType.Loop:
                    BindParam1TypeComboBox();
                    BindConditionComboBox();
                    cmbParam1Type.Enabled = true;
                    cmbParam1Value.Enabled = true;
                    cmbParam1Value.DropDownStyle = UIDropDownStyle.DropDownList;
                    cmbParam2Type.Enabled = true;
                    cmbParam2Value.Enabled = true;
                    cmbCondition.Enabled = true;
                    break;
                case ActionGroupType.FixedCount:
                    BindParam1TypeComboBox(true);
                    cmbParam1Type.Enabled = true;
                    cmbParam1Value.Enabled = true;
                    cmbParam1Value.DataSource = null;
                    cmbParam1Value.DropDownStyle = UIDropDownStyle.DropDown;
                    cmbParam2Type.DataSource = null;
                    cmbParam2Type.Enabled = false;
                    cmbParam2Value.DataSource = null;
                    cmbParam2Value.Enabled = false;
                    cmbCondition.DataSource = null;
                    cmbCondition.Enabled = false;
                    break;
            }
        }

        private void BindParam1TypeComboBox(bool isFixedCount = false)
        {
            List<ParameterComboBoxItem> list = new List<ParameterComboBoxItem>();
            if (isFixedCount)
            {
                list.Add(new ParameterComboBoxItem { DisplayText = "常量", Value = ParameterType.Const });
            }
            else
            {
                list.Add(new ParameterComboBoxItem { DisplayText = "OCR识别", Value = ParameterType.Ocr });
                list.Add(new ParameterComboBoxItem { DisplayText = "头像匹配", Value = ParameterType.Match });
            };

            cmbParam1Type.DataSource = list;
            cmbParam1Type.DisplayMember = "DisplayText";
            cmbParam1Type.ValueMember = "Value";
        }

        private void cmbParam1Type_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbParam1Type.SelectedItem == null)
                return;
            ParameterComboBoxItem cbi = cmbParam1Type.SelectedItem as ParameterComboBoxItem;
            BindParam2TypeComboBox(cbi.Value);
            switch (cbi.Value)
            {
                case ParameterType.Ocr:
                    cmbParam1Value.DataSource = DataHelper.GetActionOcrNotRegions();
                    cmbParam1Value.DisplayMember = "Name";
                    cmbParam1Value.ValueMember = "Id";
                    break;
                case ParameterType.Match:
                    cmbParam1Value.DataSource = DataHelper.GetActionImageMatches();
                    cmbParam1Value.DisplayMember = "Name";
                    cmbParam1Value.ValueMember = "Id";
                    cmbParam2Value.DataSource = new List<string> { "true", "false" };
                    cmbParam2Value.DropDownStyle = UIDropDownStyle.DropDownList;
                    break;
            }
        }

        private void BindParam2TypeComboBox(ParameterType p1type)
        {
            List<ParameterComboBoxItem> list = new List<ParameterComboBoxItem>();
            switch (p1type)
            {
                case ParameterType.Ocr:
                    list.Add(new ParameterComboBoxItem { DisplayText = "常量", Value = ParameterType.Const });
                    list.Add(new ParameterComboBoxItem { DisplayText = "OCR识别", Value = ParameterType.Ocr });
                    break;
                case ParameterType.Match:
                    list.Add(new ParameterComboBoxItem { DisplayText = "常量", Value = ParameterType.Const });
                    break;
            }

            cmbParam2Type.DataSource = list;
            cmbParam2Type.DisplayMember = "DisplayText";
            cmbParam2Type.ValueMember = "Value";
        }

        private void cmbParam2Type_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbParam2Type.SelectedItem == null)
                return;
            ParameterComboBoxItem cbi = cmbParam2Type.SelectedItem as ParameterComboBoxItem;
            switch (cbi.Value)
            {
                case ParameterType.Ocr:
                    cmbParam2Value.DataSource = DataHelper.GetActionOcrNotRegions();
                    cmbParam2Value.DisplayMember = "Name";
                    cmbParam2Value.ValueMember = "Id";
                    cmbParam2Value.DropDownStyle = UIDropDownStyle.DropDownList;
                    break;
                case ParameterType.Const:
                    cmbParam2Value.DataSource = null;
                    cmbParam2Value.DropDownStyle = UIDropDownStyle.DropDown;
                    break;
            }
        }

        private void BindConditionComboBox()
        {
            List<ConditionComboBoxItem> list = new List<ConditionComboBoxItem>()
            {
                new ConditionComboBoxItem { DisplayText = "==", Value = ConditionType.Equal },
                new ConditionComboBoxItem { DisplayText = "!=", Value = ConditionType.NotEqual },
                new ConditionComboBoxItem { DisplayText = ">=", Value = ConditionType.GreaterThanOrEqual },
                new ConditionComboBoxItem { DisplayText = ">", Value = ConditionType.GreaterThan },
                new ConditionComboBoxItem { DisplayText = "<=", Value = ConditionType.LessThanOrEqual },
                new ConditionComboBoxItem { DisplayText = "<", Value = ConditionType.LessThan },
                new ConditionComboBoxItem { DisplayText = "⊆", Value = ConditionType.Contains },
                new ConditionComboBoxItem { DisplayText = "⊈", Value = ConditionType.NotContains },
            };
            cmbCondition.DataSource = list;
            cmbCondition.DisplayMember = "DisplayText";
            cmbCondition.ValueMember = "Value";
        }
        #endregion

        /// <summary>
        /// 获取当前界面输入的ActionGroup对象
        /// </summary>
        private ActionGroup GetActionGroupFromUI()
        {
            var group = new ActionGroup
            {
                Name = txtName.Text.Trim(),
                IsDaily = txtName.Tag != null && (bool)txtName.Tag,
                GroupType = (cmbGroupType.SelectedItem as GroupTypeComboBoxItem)?.Value ?? ActionGroupType.Sequential
            };

            // 如果不是顺序执行，则需要设置参数
            if (group.GroupType != ActionGroupType.Sequential)
            {
                if (cmbParam1Type.SelectedItem != null)
                {
                    group.Param1Type = (cmbParam1Type.SelectedItem as ParameterComboBoxItem)?.Value;
                    if (group.Param1Type == ParameterType.Const)
                        group.Param1Value = cmbParam1Value.Text?.Trim();
                    else
                        group.Param1Value = cmbParam1Value.SelectedValue?.ToString();
                }

                if (group.GroupType != ActionGroupType.FixedCount)
                {
                    if (cmbParam2Type.SelectedItem != null)
                    {
                        group.Param2Type = (cmbParam2Type.SelectedItem as ParameterComboBoxItem)?.Value;
                        if (group.Param2Type == ParameterType.Const)
                            group.Param2Value = cmbParam2Value.Text?.Trim();
                        else
                            group.Param2Value = cmbParam2Value.SelectedValue?.ToString();
                    }

                    if (cmbCondition.SelectedItem != null)
                    {
                        group.Condition = (cmbCondition.SelectedItem as ConditionComboBoxItem)?.Value;
                    }
                }
            }

            return group;
        }

        /// <summary>
        /// 将ActionGroup数据设置到界面控件
        /// </summary>
        private void SetActionGroupToUI(ActionGroup group)
        {
            if (group == null) return;

            txtName.Text = group.Name;
            txtName.Tag = group.IsDaily;

            // 设置GroupType
            foreach (GroupTypeComboBoxItem item in cmbGroupType.Items)
            {
                if (item.Value == group.GroupType)
                {
                    cmbGroupType.SelectedItem = item;
                    break;
                }
            }

            // 如果有参数，设置参数
            if (group.Param1Type.HasValue)
            {
                foreach (ParameterComboBoxItem item in cmbParam1Type.Items)
                {
                    if (item.Value == group.Param1Type.Value)
                    {
                        cmbParam1Type.SelectedItem = item;
                        break;
                    }
                }
                if (group.Param1Type == ParameterType.Const)
                    cmbParam1Value.Text = group.Param1Value;
                else
                    if (int.TryParse(group.Param1Value, out int sv))
                    cmbParam1Value.SelectedValue = sv;
                else
                    cmbParam1Value.Text = group.Param1Value;
            }

            if (group.Param2Type.HasValue)
            {
                foreach (ParameterComboBoxItem item in cmbParam2Type.Items)
                {
                    if (item.Value == group.Param2Type.Value)
                    {
                        cmbParam2Type.SelectedItem = item;
                        break;
                    }
                }
                if (group.Param2Type == ParameterType.Const)
                    cmbParam2Value.Text = group.Param2Value;
                else
                    if (int.TryParse(group.Param2Value, out int sv))
                    cmbParam2Value.SelectedValue = sv;
                else
                    cmbParam2Value.Text = group.Param2Value;
            }

            if (group.Condition.HasValue)
            {
                foreach (ConditionComboBoxItem item in cmbCondition.Items)
                {
                    if (item.Value == group.Condition.Value)
                    {
                        cmbCondition.SelectedItem = item;
                        break;
                    }
                }
            }
            btnEnqueue.Visible = true;
            btnEnqueue5.Visible = true;
        }

        /// <summary>
        /// 清除界面输入
        /// </summary>
        private void ClearUI()
        {
            txtName.Text = string.Empty;

            // 设置为顺序执行
            foreach (GroupTypeComboBoxItem item in cmbGroupType.Items)
            {
                if (item.Value == ActionGroupType.Sequential)
                {
                    cmbGroupType.SelectedItem = item;
                    break;
                }
            }

            // 清除其他控件
            cmbParam1Type.DataSource = null;
            cmbParam1Value.DataSource = null;
            cmbParam2Type.DataSource = null;
            cmbParam2Value.DataSource = null;
            cmbCondition.DataSource = null;
            btnEnqueue.Visible = false;
            btnEnqueue5.Visible = false;
            btnDelete.Visible = false;

            // 清除DataGridView选择
            dgvActions.ClearSelection();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(txtName.Text))
                {
                    this.ShowWarningTip("请输入动作组名称");
                    return;
                }

                var group = GetActionGroupFromUI();
                var selectedRow = dgvActions.SelectedRows.Count > 0 ? dgvActions.SelectedRows[0] : null;

                // 检查是否存在同名的ActionGroup
                var groups = DataHelper.GetActionGroups();
                var existingGroup = groups.FirstOrDefault(g => g.Name == group.Name);

                if (selectedRow == null) // 新增
                {
                    if (existingGroup != null)
                    {
                        if (this.ShowAskDialog("已存在同名的动作组，是否更新？"))
                        {
                            group.Id = existingGroup.Id;
                            if (DataHelper.UpdateActionGroup(group))
                            {
                                this.ShowSuccessTip("更新成功");
                                LoadData();
                                ClearUI();
                            }
                        }
                    }
                    else
                    {
                        if (DataHelper.InsertActionGroup(group))
                        {
                            this.ShowSuccessTip("保存成功");
                            LoadData();
                            ClearUI();
                        }
                    }
                }
                else // 更新
                {
                    var currentName = selectedRow.Cells["ColumnName"].Value.ToString();
                    if (existingGroup != null && existingGroup.Name != currentName)
                    {
                        this.ShowWarningTip("已存在同名的动作组");
                        return;
                    }

                    var currentGroup = groups.First(g => g.Name == currentName);
                    group.Id = currentGroup.Id;
                    if (DataHelper.UpdateActionGroup(group))
                    {
                        this.ShowSuccessTip("更新成功");
                        LoadData();
                        ClearUI();
                    }
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorTip("保存失败：" + ex.Message);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            ClearUI();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                var selectedRow = dgvActions.SelectedRows.Count > 0 ? dgvActions.SelectedRows[0] : null;
                if (selectedRow == null)
                {
                    this.ShowWarningTip("请选择要删除的动作组");
                    return;
                }

                var name = selectedRow.Cells["ColumnName"].Value.ToString();
                var itemCount = Convert.ToInt32(selectedRow.Cells["ColumnActionGroupItems"].Value);
                if (itemCount > 0)
                {
                    this.ShowWarningTip("该动作组包含子项，不能删除");
                    return;
                }

                if (this.ShowAskDialog($"确定要删除动作组{name}吗？"))
                {
                    var groups = DataHelper.GetActionGroups();
                    var group = groups.First(g => g.Name == name);
                    if (DataHelper.DeleteActionGroup(group.Id))
                    {
                        this.ShowSuccessTip("删除成功");
                        LoadData();
                        ClearUI();
                    }
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorTip("删除失败：" + ex.Message);
            }
        }

        private void dgvActions_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                var selectedRow = dgvActions.SelectedRows.Count > 0 ? dgvActions.SelectedRows[0] : null;
                if (selectedRow != null)
                {
                    //selectedRow.DataBoundItem
                    var name = selectedRow.Cells["ColumnName"].Value.ToString();
                    var groups = DataHelper.GetActionGroups();
                    var group = groups.First(g => g.Name == name);
                    SetActionGroupToUI(group);

                    // 如果有子项，隐藏删除按钮
                    var itemCount = Convert.ToInt32(selectedRow.Cells["ColumnActionGroupItems"].Value);
                    btnDelete.Visible = itemCount == 0;
                    btnTest.Visible = itemCount != 0;
                }
                else
                {
                    ClearUI();
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorTip("数据表选择错误：" + ex.Message);
            }
        }

        private void dgvActions_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.RowIndex >= 0)
                {
                    var name = dgvActions.Rows[e.RowIndex].Cells["ColumnName"].Value.ToString();
                    var groups = DataHelper.GetActionGroups();
                    var group = groups.First(g => g.Name == name);

                    var dialog = new DialogActionGroupItems(group);
                    dialog.PageActionGroups = this;
                    dialog.Show();
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorTip("打开动作组项目失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 加载动作组数据
        /// </summary>
        private void LoadData()
        {
            try
            {
                var groups = DataHelper.GetActionGroups();
                dgvActions.DataSource = groups.Select(g => new
                {
                    g.Id,
                    g.Name,
                    g.IsDaily,
                    GroupType = GetGroupTypeText(g.GroupType),
                    Pcp = GetGroupPcpText(g),
                    ActionGroupItemCounts = g.ActionGroupItems.Count
                }).ToList();
            }
            catch (Exception ex)
            {
                this.ShowErrorTip("加载动作组数据失败：" + ex.Message);
            }
        }

        private string GetGroupPcpText(ActionGroup g)
        {
            switch (g.GroupType)
            {
                case ActionGroupType.Sequential:
                    return string.Empty;
                case ActionGroupType.Branch:
                case ActionGroupType.Loop:
                    string c = string.Empty;
                    switch (g.Condition)
                    {
                        case ConditionType.LessThan:
                            c = "<";
                            break;
                        case ConditionType.LessThanOrEqual:
                            c = "<=";
                            break;
                        case ConditionType.GreaterThan:
                            c = ">";
                            break;
                        case ConditionType.GreaterThanOrEqual:
                            c = ">=";
                            break;
                        case ConditionType.Equal:
                            c = "=";
                            break;
                        case ConditionType.NotEqual:
                            c = "!=";
                            break;
                        case ConditionType.Contains:
                            c = "⊆";
                            break;
                        case ConditionType.NotContains:
                            c = "⊈";
                            break;
                        default:
                            c = string.Empty;
                            break;
                    }
                    string p1v = string.Empty;
                    switch (g.Param1Type)
                    {
                        case ParameterType.Ocr:
                            var ocrAction = DataHelper.GetActionOcrById(int.Parse(g.Param1Value));
                            p1v = ocrAction.Name;
                            break;
                        case ParameterType.Match:
                            var matchAction = DataHelper.GetActionImageMatchById(int.Parse(g.Param1Value));
                            p1v = matchAction.Name;
                            break;
                        default:
                            p1v = g.Param1Value;
                            break;
                    }
                    string p2v = string.Empty;
                    switch (g.Param2Type)
                    {
                        case ParameterType.Ocr:
                            var ocrAction = DataHelper.GetActionOcrById(int.Parse(g.Param2Value));
                            p2v = ocrAction.Name;
                            break;
                        case ParameterType.Match:
                            var matchAction = DataHelper.GetActionImageMatchById(int.Parse(g.Param2Value));
                            p2v = matchAction.Name;
                            break;
                        default:
                            p2v = g.Param2Value;
                            break;
                    }
                    return $"{p1v}{c}{p2v}";
                case ActionGroupType.FixedCount:
                    return $"{g.Param1Value}次";
                default:
                    return string.Empty;
            }
        }

        /// <summary>
        /// 获取动作组类型的中文显示文本
        /// </summary>
        private string GetGroupTypeText(ActionGroupType type)
        {
            switch (type)
            {
                case ActionGroupType.Sequential:
                    return "顺序";
                case ActionGroupType.Branch:
                    return "分支";
                case ActionGroupType.Loop:
                    return "循环";
                case ActionGroupType.FixedCount:
                    return "定次";
                default:
                    return type.ToString();
            }
        }

        private async void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                var selectedRow = dgvActions.SelectedRows.Count > 0 ? dgvActions.SelectedRows[0] : null;
                if (selectedRow != null)
                {
                    //selectedRow.DataBoundItem
                    var name = selectedRow.Cells["ColumnName"].Value.ToString();
                    var groups = DataHelper.GetActionGroups();
                    ActionGroup group = groups.First(g => g.Name == name);
                    group.WebView = _webView;
                    group.Completed += (c, e) =>
                    {
                        panelInfo.Text = e.Descprition;
                    };
                    panelInfo.Text = $"{group.Name}开始";
                    ActionResult rst = await group.ExecuteAsync();
                    panelInfo.Text = rst.Descprition;
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorTip("数据表选择错误：" + ex.Message);
            }
        }

        public void RefreshActionGroup()
        {
            LoadData();
        }

        private void btnEnqueue_Click(object sender, EventArgs e)
        {
            UISymbolButton btn = sender as UISymbolButton;
            int.TryParse(btn.TagString, out int count);
            try
            {
                var selectedRow = dgvActions.SelectedRows.Count > 0 ? dgvActions.SelectedRows[0] : null;
                if (selectedRow != null)
                {
                    //selectedRow.DataBoundItem
                    var name = selectedRow.Cells["ColumnName"].Value.ToString();                    
                    if (_pageRunner != null)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            var groups = DataHelper.GetActionGroups();
                            ActionGroup group = groups.First(g => g.Name == name);
                            _pageRunner.AddToRun(group);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.ShowErrorNotifier("选择动作群组错误：" + ex.Message);
            }
        }

        private void dgvActions_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            try
            {
                var row = dgvActions.Rows[e.RowIndex];
                var dr = row.DataBoundItem as dynamic;
                
                if (dr.IsDaily)
                {
                    // 在行头绘制一个红色圆点标记
                    var rect = new Rectangle(e.RowBounds.Left + 20, e.RowBounds.Top + (e.RowBounds.Height - 8) / 2, 8, 8);
                    using (var brush = new SolidBrush(Color.Red))
                    {
                        e.Graphics.FillEllipse(brush, rect);
                    }
                }
            }
            catch (Exception ex)
            {
                // 绘制错误不影响主程序运行
                System.Diagnostics.Debug.WriteLine($"行头绘制错误：{ex.Message}");
            }
        }
    }

    public class ParameterComboBoxItem
    {
        public string DisplayText { get; set; } // 显示的文本
        public ParameterType Value { get; set; }          // 对应的值

        public override string ToString()
        {
            return DisplayText; // 用于在 UIComboBox 中显示
        }
    }

    public class GroupTypeComboBoxItem
    {
        public string DisplayText { get; set; } // 显示的文本
        public ActionGroupType Value { get; set; }          // 对应的值

        public override string ToString()
        {
            return DisplayText; // 用于在 UIComboBox 中显示
        }
    }

    public class ConditionComboBoxItem
    {
        public string DisplayText { get; set; } // 显示的文本
        public ConditionType Value { get; set; }          // 对应的值

        public override string ToString()
        {
            return DisplayText; // 用于在 UIComboBox 中显示
        }
    }
}
